package com.cskaoyan.javase.oop2._1extends._9override._2grammar;

/**
 * 方法的重写(override)/覆盖的语法
 * 方法的重写这里针对父类中的成员方法：
 * [访问权限修饰符] 返回值类型 方法名(形参列表){
 *     // 方法体
 * }
 * 为了能够更加清晰的看到子类重写父类的方法,也便于检查方法重写的正确性
 * 解释: 该注解写在子类重写的父类方法的方法头上,用于检验方法重写正确性.
 * 要求在使用方法重写时,必须写注解"@Override"
 * 好处:
 *      1.增加代码的可读性
 *      2.检验重写的语法
 *
 * 方法的重写首先需要前提：方法的重写必须发生在继承中的两个类中,父类和子类中
 * 并且父子类中的方法要同名,必须同名
 * 逐一解释:
 * 1.访问权限修饰符
 *      子类在重写父类方法时,可以选择修改父类方法的访问权限修饰符
 *      但是不是乱改的: 子类只能把权限改的更加宽松,或者保持一致,不能更严格
 *
 * 2.返回值类型
 *      子类在重写父类方法时,是可以修改父类方法的返回值类型的,但是并不是什么都能改
 *      子类重写方法的返回值类型要和父类方法的返回值类保持"兼容"
 *      晚上大家自行测试一下
 *
 * 3.方法名必须保持一致
 *
 * 4.形参列表必须保持一致,不能做任何修改.
 *
 * 5.方法体没有要求,可以和父类保持一致,也可以随便写.
 *
 * 补充:
 * 1.方法重写时,每次都要复制父类方法然后加上注解"@Override",这种方法太笨了
 * 推荐以下方式重写父类方法:
 *      a.如果已经知道想重写父类哪个方法,可以直接在子类类体中写父类方法的名字,看到提示后,回车即可
 *      b.假如不知道要重写哪个方法,希望能够选择
 *      可以使用 快捷键 alt + insert
 *
 * 2.方法的重写(override) vs 方法的重载(overload)
 * 相同点:
 *      1.方法名都要求必须相同
 *      2.方法体都没有要求,随便写
 * 不同点:
 *      1.重写是两个父子类之间
 *      重载必须在同一个类中
 *
 *      2.重写要求访问权限修饰符不能更严格
 *      但是重载没有要求
 *
 *      3.重写要求返回值类型"兼容"
 *      但是重载没有要求
 *
 *      4.重写要求形参列表必须相同
 *      但是重载要求必须不相同
 *
 *
 * @since 09:50
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Father fs = new Son();
        fs.test();
    }
}

class Father {
    protected void test() {
        System.out.println("father");
    }

    void method() {

    }
}

class Son extends Father {

    // Method does not override method from its superclass
    @Override
    protected void test() {
        System.out.println("son");
    }

    @Override
    void method() {
        super.method();
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }


}
